package com.hsgene.generator.util.generator;

import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

/**
 * 编号生成器
 *
 * @author wangbing
 * @version 1.0, 2018/6/29
 */
public abstract class AbstractGenerator {

    protected final static String REDIS_PREFIX_KEY = "ms-mod-generator:";

    protected StringRedisTemplate stringRedisTemplate;

    /**
     * 构建编号
     *
     * @param prefix 编号前缀
     * @return 编号信息
     */
    public abstract String generate(String prefix);

    public void setRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    /**
     * 获取自增后缀
     *
     * @param key 键
     * @return 后缀值
     */
    @SuppressWarnings("all")
    protected synchronized Integer getIncrementSuffix(final String key) {
        SessionCallback<String> sessionCallback = new SessionCallback<String>() {
            @Override
            public String execute(RedisOperations redisOperations) throws DataAccessException {
                String suffix = (String) redisOperations.opsForValue().get(key);
                redisOperations.watch(key);
                redisOperations.multi();
                if (StringUtils.isEmpty(suffix)) {
                    suffix = "1";
                    redisOperations.opsForValue().set(key, suffix, 1L, TimeUnit.MINUTES);
                }
                redisOperations.opsForValue().increment(key, 1L);
                redisOperations.exec();
                redisOperations.unwatch();
                return suffix;
            }
        };
        String suffix = stringRedisTemplate.execute(sessionCallback);

        return Integer.valueOf(suffix);
    }

}
